(function() {
	var jquery = function(param) {
		return new jquery.prototype.init(param);
	}

	//方法类
	jquery.prototype = {
		init: function(param) {
			var param = param.trim();
			this[0] = document.querySelectorAll(param);
			console.log(param);
			console.log(this[0]);
			return this;
		},
		//DOM渲染
		ready: function(fn) {
			//对于现代浏览器，对DOMContentLoaded事件的处理采用标准的事件绑定方式
			if(document.addEventListener) {
				document.addEventListener("DOMContentLoaded", fn, false);
			} else {
				IEContentLoaded(fn);
			}

			//IE模拟DOMContentLoaded
			function IEContentLoaded(fn) {
				var d = window.document;
				var done = false;

				//只执行一次用户的回调函数init()
				var init = function() {
					if(!done) {
						done = true;
						fn();
					}
				};

				(function() {
					try {
						// DOM树未创建完之前调用doScroll会抛出错误
						d.documentElement.doScroll('left');
					} catch(e) {
						//延迟再试一次~
						setTimeout(arguments.callee, 50);
						return;
					}
					// 没有错误就表示DOM树创建完毕，然后立马执行用户回调
					init();
				})();

				//监听document的加载状态
				d.onreadystatechange = function() {
					// 如果用户是在domReady之后绑定的函数，就立马执行
					if(d.readyState == 'complete') {
						d.onreadystatechange = null;
						init();
					}
				}
			}
		},
		/*---------------HTML篇-----------------*/
		html(arg) {
			eachNode(this[0], "innerHTML", arg);
			return this;
		}
		text(arg) {
			eachNode(this[0], "innerText", arg);
			return this;
		}
		//添加css成功
		css(arg) {
			this[0].forEach((item) => {
				for(let i in arg) {
					item.style[i] = arg[i];
				}
			})
			return this;
		}
		//添加class成功
		addClass(arg) {
			console.log(this);
			this[0].forEach((item) => {
				for(let i = 0; i < arg.length; i++) {
					item.classList.add(arg[i]);
				}
			})
			return this;
		}

		//删除class单个样式成功
		removeClass(sclass) {
			this[0].forEach((item) => {
				for(let i = 0; i < arguments.length; i++) {
					item.classList.remove(arguments[i]);
				}
			})
			return this;
		}
		toggleClass(arg) {
			for(var i = 0; i < arg.length; i++) {
				this[0].forEach((item) => {
					if(item.classList.contains(arg[i])) {
						item.classList.remove(arg[i]);
					} else {
						item.classList.add(arg[i]);
					}
				})
			}
		}
		//添加attr单个属性成功
		attr(name, arg) {
			eachNode(this[0], `setAttribute[${name}]`, arg);
			return this;
		}
		//清除空格，无法清除中间
		trim(str) {
			return str.trim();
		}
		//清除空格，包括中间
		trimAll(str) {
			str = str.replace(/\s*/g, "");    //所有空格
			str = str.replace(/^\s*|\s*$/g, ""); //两头空格
			str = str.replace(/^\s*/, ""); //左空格
			str = str.replace(/(\s*$)/g, ""); //右空格
			return str;
		}
		//设置表单的值成功(成功)
		val(arg) {
			if(arg != null) {
				eachNode(this[0], "value", arg);
				return this;
			} else {
				return this[0][0].value;
			}
		}
		//append/prepend 是在选择元素内部嵌入。
		//after/before 是在元素外面追加。
		after(arg) {
			this[0].forEach((item) => {
				item = item.after(arguments);
			})
			return this;
		}
		before(arg) {
			this[0].forEach((item) => {
				item = item.before(arguments);
			})
			return this;
		}
		//前面追加节点成功
		prepend(arg) {
			this[0].forEach((item) => {
				item.innerHTML = arg + item.innerHTML;
			})
			return this;
		}
		//后面追加节点成功
		append(arg) {
			this[0].forEach((item) => {
				item.innerHTML += arg;
			})
			return this;
		}
		remove(arg) {
			this[0].forEach((item) => {
				delete item.arg;
			})
			return this;
		}

		//设置高度成功(不包括内边距、边框或外边距)
		height(arg) {
			eachNode(this[0], "clientHeight", arg);
			return this;
		}
		//设置宽度成功(不包括内边距、边框或外边距)
		width(arg) {
			eachNode(this[0], "clientWidth", arg);
			return this;
		}
		//设置高度成功(包括内边距)。
		innerHeight(arg) {
			eachNode(this[0], "innerHeight", arg);
			return this;
		}
		//设置宽度成功(包括内边距)。
		innerWidth(arg) {
			eachNode(this[0], "innerWidth", arg);
			return this;
		}
		//设置高度成功(包括内边距和边框)。
		outerHeight(arg) {
			eachNode(this[0], "outerHeight", arg);
			return this;
		}
		//设置宽度成功(包括内边距和边框)。
		outerWidth(arg) {
			eachNode(this[0], "outerWidth", arg);
			return this;
		}
		/*--------事件篇---------*/
		click(fun) {
			eachEvent(this[0], "onclick", fun);
			return this;
		}
		dblclick(fun) {
			eachEvent(this[0], "ondbclick", fun);
			return this;
		}
		mouseup(fun) {
			eachEvent(this[0], "onmouseup", fun);
			return this;
		}
		focus(fun) {
			eachEvent(this[0], "onfocus", fun);
			return this;
		}
		blur(fun) {
			eachEvent(this[0], "onblur", fun);
			return this;
		}
		select(fun) {
			eachEvent(this[0], "onselect", fun);
			return this;
		}
		change(fun) {
			eachEvent(this[0], "onchange", fun);
			return this;
		}
		onload(fun) {
			eachEvent(this[0], "onload", fun);
			return this;
		}
		unload(fun) {
			eachEvent(this[0], "onunload", fun);
			return this;
		}
		mouseover(fun) {
			eachEvent(this[0], "onmouseover", fun);
			return this;
		}
		mouseout(fun) {
			eachEvent(this[0], "onmouseout", fun);
			return this;
		}
		//移入移出事件成功
		hover(fun1, fun2) {
			eachEvent(this[0], "onmouseover", fun1);
			eachEvent(this[0], "onmouseout", fun2);
			return this;
		}
		mouseenter(fun) {
			eachEvent(this[0], "mouseenter", fun);
			return this;
		}
		mouseleave(fun) {
			eachEvent(this[0], "mouseleave", fun);
			return this;
		}
		keypress(fun) {
			eachEvent(this[0], "onkeypress", fun);
			return this;
		}
		keydown(fun) {
			eachEvent(this[0], "onkeydown", fun);
			return this;
		}
		keyup(fun) {
			eachEvent(this[0], "onkeyup", fun);
			return this;
		}
		submit(fun) {
			eachEvent(this[0], "onsubmit", fun);
			return this;
		}
		resize(fun) {
			eachEvent(this[0], "onresize", fun);
			return this;
		}
		scroll(fun) {
			eachEvent(this[0], "onscroll", fun);
			return this;
		}
		/*--------效果篇---------*/
		//淡入成功
		show(time = 200, callback = null) {
			let num = 0;
			this[0].forEach((item) => {
				item.style.display = "block";
				item.style.opacity = num;
			})
			let st = setInterval(() => {
				num++;
				this[0].forEach((item) => {
					item.style.opacity = num / 10;
				})
				if(num >= 10) {
					clearInterval(st);
					if(callback != null) {
						callback()
					}
				}
			}, time)
			return this;
		}
		//淡出成功
		hide(time = 200, callback) {
			let num = 10;
			let st = setInterval(() => {
				num--;
				this[0].forEach((item) => {
					item.style.opacity = num / 10;
				})
				if(num <= 0) {
					clearInterval(st);
					if(callback != null) {
						callback()
					}
				}
			}, time)
			return this;
		}

		//动画
		animate(json, interval, sp, fn) {
			this[0].forEach((item) => {
				this.animateRun(item, json, interval, sp, fn);
			})
		}
		animateRun(obj, json, interval, sp, fn) {
			clearInterval(obj.timer);
			obj.timer = setInterval(() => {
				//j ++;
				var flag = true;
				for(var arr in json) {
					var icur = 0;
					if(arr == "opacity") {
						icur = Math.round(parseFloat(document.defaultView.getComputedStyle(obj, null)[arr]) * 100);
					} else {
						icur = parseInt(document.defaultView.getComputedStyle(obj, null)[arr]);
					}
					var speed = (json[arr] - icur) * sp;
					speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
					if(icur != json[arr]) {
						flag = false;
					}
					if(arr == "opacity") {
						obj.style.filter = "alpha(opacity : '+(icur + speed)+' )";
						obj.style.opacity = (icur + speed) / 100;
					} else {
						obj.style[arr] = icur + speed + "px";
					}
				}
				if(flag) {
					clearInterval(obj.timer);
					if(fn) {
						fn();
					}
				}
			}, interval);
		}
		stop() {
			this.animate(null, null, null, null);
		}

		/*----------遍历篇-----------*/
		empty() {
			this[0].forEach((item) => {
				if(item.children) {
					delete item.children
				}
			})
			return this;
		}
		each(object, callback) {
			var type = (function() {
				switch(object.constructor) {
					case Object:
						return 'Object';
						break;
					case Array:
						return 'Array';
						break;
					case NodeList:
						return 'NodeList';
						break;
					default:
						return 'null';
						break;
				}
			})();
			// 为数组或类数组时, 返回: index, value
			if(type === 'Array' || type === 'NodeList') {
				// 由于存在类数组NodeList, 所以不能直接调用every方法
				[].every.call(object, function(v, i) {
					return callback.call(v, i, v) === false ? false : true;
				});
			}
			// 为对象格式时,返回:key, value
			else if(type === 'Object') {
				for(var i in object) {
					if(callback.call(object[i], i, object[i]) === false) {
						break;
					}
				}
			}
			return this;
		}

		//获取所有父元素未成功
		parents() {
			this[0].forEach((item) => {
				item = item.offsetParent;
			})
		}
		//获取单个父元素成功
		parent() {
			this[0].forEach((item) => {
				item = item.parentNode;
			})
			return this;
		}
		//获取所有下一级的子元素成功
		children(num) {
			let temp = [];
			if(this[0].length > 1) {
				for(let i = 0; i < this[0].length; i++) {
					if(num == undefined) {
						if(this[0][i].children.length > 1) {
							for(let j = 0; j < this[0][i].children.length; j++) {
								temp.push(this[0][i].children[j]);
							}
						} else {
							temp.push(this[0][i].children);
						}
					} else {
						temp.push(this[0][i].children[num]);
					}
				}
				this[0] = temp;
			} else {
				this[0] = this[0].children[num];
			}
			console.log(this[0]);
			console.log(this);
			return this;
		}
		//获取所有兄弟节点,不包括本身
		siblings(arg) {
			let a = []; //保存所有兄弟节点
			this[0].forEach((item) => {
				var p = item.parentNode.children; //获取父级的所有子节点
				for(let i = 0; i < p.length; i++) { //循环
					if(p[i].nodeType == 1 && p[i] != item) { //如果该节点是元素节点与不是这个节点本身
						a.push(p[i]); // 添加到兄弟节点里
					}
				}
			})
			this[0] = a;
			return this;
		}
		next() {
			this[0].forEach((item) => {
				item = item.nextElementSibling;
			})
			return this;
		}
		nextAll() {
			this[0].forEach((item) => {
				item = item.nextElementSibling;
			})
			return this;
		}
		prev() {
			this[0].forEach((item) => {
				item = item.previousElementSibling;
			})
			return this;
		}
		prevAll() {
			let a = []; //保存所有兄弟节点
			this[0].forEach((item) => {
				var p = item.parentNode.children; //获取父级的所有子节点
				for(let i = 0; i < p.length; i++) { //循环
					a.push(p[i]); // 添加到兄弟节点里
					if(p[i] == item) { //如果该节点是元素节点与不是这个节点本身
						break;
					}
				}
			})
			this[0] = a;
			return this;

		}
		first() {
			this[0].forEach((item) => {
				item = item.firstElementChild;
			})
			return this;
		}
		last() {
			this[0].forEach((item) => {
				item = item.lastElementChild;
			})
			return this;
		}
		eq(index) {
			this[0].forEach((item) => {
				item = item[index];
			})
			return this;
		}
		filter(arg) {
			for(let i = 0; i < this[0].length; i++) {
				if(this[0][i].className != arg) {
					this[0].splice(i, 1);
					i--
				}
			}
			return this;
		}
		not(arg) {
			for(let i = 0; i < this[0].length; i++) {
				if(this[0][i].className == arg) {
					this[0].splice(i, 1);
					i--
				}
			}
			return this;
		}

	}
	jquery.ajax = function(){
		//获取ajax的相应值（请求类型，请求地址，同步或异步，传递数据，接收数据类型，成功失败函数等）
        let ajaxData = {
            type: arguments[0].type || "GET",
            url: arguments[0].url || "",
            async: arguments[0].async || "true",
            data: arguments[0].data || null,
            dataType: arguments[0].dataType || "text",
            contentType: arguments[0].contentType || "application/x-www-form-urlencoded",
            beforeSend: arguments[0].beforeSend || function() {},
            success: arguments[0].success || function() {},
            error: arguments[0].error || function() {}
        }
        ajaxData.beforeSend()
        let xhr = new XMLHttpRequest(); //创建 XMLHttpRequest 对象
        xhr.responseType = ajaxData.dataType; //预期服务器返回的数据类型
        xhr.open(ajaxData.type, ajaxData.url, ajaxData.async); //规定请求的类型、URL 以及是否异步处理请求
        xhr.setRequestHeader("Content-Type", ajaxData.contentType); //发送信息至服务器时内容编码类型(向请求添加 HTTP 头)
        xhr.send(convertData(ajaxData.data)); //将请求发送到服务器
        //当请求被发送到服务器时，我们需要执行一些基于响应的任务。
        //每当 readyState 改变时，就会触发 onreadystatechange 事件。
        //readyState 属性存有 XMLHttpRequest 的状态信息。
        xhr.onreadystatechange = function() {
            if(xhr.readyState == 4) {
                if(xhr.status == 200) {
                    ajaxData.success(xhr.response)
                } else {
                    ajaxData.error()
                }
            }
        }
	}
	jquery.prototype.init.prototype = jquery.prototype; //把jq的原型赋值给init的原型
	window.$ = window.jquery = jquery;
})();
function eachNode(obj,attribute,arg){
    obj.forEach((item)=>{
        item[attribute] = arg
    })
}
function eachEvent(obj,attribute,arg){
    obj.forEach((item)=>{
        item[attribute] = arg
    })
}
function isDOM(obj) {
    if(typeof HTMLElement === 'object') {
        return obj instanceof HTMLElement;
    } else {
        return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
    }
}
function convertData(data) {
    if(typeof data === 'object') {
        var convertResult = "";
        for(var c in data) {
            convertResult += c + "=" + data[c] + "&";
        }
        convertResult = convertResult.substring(0, convertResult.length - 1)
        return convertResult;
    } else {
        return data;
    }
}